package com.vt.common.core.util;

import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import org.apache.poi.xssf.streaming.SXSSFSheet;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.*;

/**
 * @Auther: PanZha
 * @Date: 2018/10/25 18:13
 */
public class ExcelDataUtil {

    public static List<Map<String, Object>> filter(List list, Dict dict) throws IllegalAccessException {
        List<Map<String, Object>> rs = new ArrayList<>();
        Map<String, Object> map;

        List<String> ks = new ArrayList(dict.keySet());
        for (int i = 0, size = list.size(); i < size; i++) {
            map = beanToMap(list.get(i), ks);
            rs.add(map);
        }
        return rs;
    }

    /**
     * bean to map ，按 ks 顺序
     *
     * @param obj
     * @param ks
     * @return
     * @throws IllegalAccessException
     */
    private static Map<String, Object> beanToMap(Object obj, List<String> ks) throws IllegalAccessException {
        Map<String, Object> map = new LinkedHashMap<>();
        Field[] fs = ReflectUtil.getFields(obj.getClass());

        String name;
        for (int i = 0, len = fs.length; i < len; i++) {
            name = fs[i].getName();
            if (ks.contains(name)) {
                map.put(name, ReflectUtil.getFieldValue(obj, fs[i]));
            }
        }
        return map;
    }


    public static void autoSizeColumn(ExcelWriter writer, int size) {
        ((SXSSFSheet) writer.getSheet()).trackAllColumnsForAutoSizing();
        for (int i = 0; i < size; i++) {
            writer.autoSizeColumn(i);
        }
    }

    public static void write(List list, Dict dict, HttpServletResponse resp, String fileName) throws IOException, IllegalAccessException {
        List<Map<String, Object>> data = filter(list, dict);

        ExcelWriter writer = ExcelUtil.getBigWriter();

        //headerAlias
        setHeaderAlias(writer, dict);
        //write
        writer.write(data);

        //auto size
        autoSizeColumn(writer, dict.size());

        String name = URLEncoder.encode(fileName, "UTF-8");
        resp.setContentType("application/vnd.ms-excel;charset=utf-8");
        resp.setHeader("Content-Disposition", "attachment;filename=" + name + ".xlsx");

        //刷新到 response
        writer.flush(resp.getOutputStream());
        //关闭writer，释放内存
        writer.close();
    }

    public static void setHeaderAlias(ExcelWriter writer, Dict dict) {
        Set<String> ks = dict.keySet();

        for (String k : ks) {
            writer.addHeaderAlias(k, dict.getStr(k));
        }
    }
}
